﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Win32;
using System.ServiceProcess;
using System.Threading;

namespace Meerkat_Frontend
{
    public partial class frmMain : Form
    {
        private bool _FormLoaded = false;
        private string _RegistryRoot = @"Software\Kensei\Meerkat";

        public frmMain()
        {
            InitializeComponent();
            InitializeRegistry();
            GetDrives();
            LoadSettings();
            _FormLoaded = true;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            this.Size = new System.Drawing.Size(311, 350);
            this.CenterToScreen();
        }

        private void InitializeRegistry()
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey(_RegistryRoot);
            if (key == null)
            {
                Registry.LocalMachine.CreateSubKey(_RegistryRoot);
            }
        }

        public void GetDrives()
        {
            DriveInfo[] allDrives = DriveInfo.GetDrives();
            foreach (DriveInfo dirInfo in allDrives)
            {
                if (dirInfo.IsReady)
                {
                    string DriveLabel = dirInfo.Name.Replace(@"\", "") + " " + dirInfo.VolumeLabel;
                    if (string.IsNullOrEmpty(dirInfo.VolumeLabel))
                    {
                        if (dirInfo.DriveType == DriveType.Fixed)
                        {
                            DriveLabel += "Local Disk";
                        }
                        else if (dirInfo.DriveType == DriveType.Removable || dirInfo.DriveType == DriveType.CDRom)
                        {
                            DriveLabel += "Removable Disk";
                        }
                        else if (dirInfo.DriveType == DriveType.Network)
                        {
                            DriveLabel += "Networked Disk";
                        }
                        else
                        {
                            DriveLabel += "Unknown Disk";
                        }
                    }
                    clbDisks.Items.Add(DriveLabel + "   [" + ConvertBytes(Convert.ToInt64(dirInfo.TotalFreeSpace)) + " free of " + ConvertBytes(Convert.ToInt64(dirInfo.TotalSize)) + "]",false);
                }
            }
        }

        public string ConvertBytes(Int64 byteCount)
        {
            string size = "0 Bytes";
            if (byteCount >= 1073741824)
                size = String.Format("{0:##.##}", byteCount / 1073741824) + " GB";
            else if (byteCount >= 1048576)
                size = String.Format("{0:##.##}", byteCount / 1048576) + " MB";
            else if (byteCount >= 1024)
                size = String.Format("{0:##.##}", byteCount / 1024) + " KB";
            else if (byteCount > 0 && byteCount < 1024)
                size = byteCount.ToString() + " Bytes";

            return size;
        }

        private void SaveAllSettings()
        {
            SaveDiskSettings();
            SaveAlertSettings();
            SaveEmailAddresses();
            SaveEmailOptions();
        }

        public void SaveDiskSettings()
        {
            //if the form is still drawing, don't do control change save
            if (!_FormLoaded) return;

            //delete existing settings
            RegistryKey key = Registry.LocalMachine.OpenSubKey(_RegistryRoot + @"\Disks");
            if (key != null)
            {
                key = Registry.LocalMachine.CreateSubKey(_RegistryRoot);
                key.DeleteSubKeyTree("Disks");
            }

            //save new settings
            foreach (string i in clbDisks.CheckedItems)
            {
                key = Registry.LocalMachine.CreateSubKey(_RegistryRoot + @"\Disks");
                key.SetValue(i.Substring(i.IndexOf("(") + 1, 1), "1");
                //Console.WriteLine("saved disk " + i + " to registry");
            }
        }

        public void SaveAlertSettings()
        {
            //if the form is still drawing, don't do control change save
            if (!_FormLoaded) return;
            
            //delete existing settings
            RegistryKey key = Registry.LocalMachine.CreateSubKey(_RegistryRoot);
            try
            {
                key.DeleteSubKey("Threshold");
            }
            catch { }

            key = Registry.LocalMachine.CreateSubKey(_RegistryRoot + @"\Threshold");
            if (cboAmount.SelectedItem!=null) key.SetValue("Amount",cboAmount.SelectedItem);
            if (cboUnit.SelectedItem != null) key.SetValue("Unit", cboUnit.SelectedItem);

            Console.WriteLine("threshold settings saved to registry");
        }

        public void SaveEmailAddresses()
        {
            string EmailAddresses = "";

            foreach (DataGridViewRow dr in dgEmailAddresses.Rows)
            {
                if (dr.Cells[0].Value != null)
                {
                    EmailAddresses+=dr.Cells[0].Value.ToString() + ";";
                }
            }

            RegistryKey key = Registry.LocalMachine.CreateSubKey(_RegistryRoot);
            if (!string.IsNullOrEmpty(EmailAddresses))
            {
                EmailAddresses = EmailAddresses.Substring(0, EmailAddresses.Length - 1);
                key.SetValue("EmailAddresses", EmailAddresses);
            }
        }

        private void SaveEmailOptions()
        {
            RegistryKey key = Registry.LocalMachine.CreateSubKey(_RegistryRoot);
            key.SetValue("MachineName", txtMachineName.Text);
            key.SetValue("SmtpServer", txtSmtpServer.Text);
            key.SetValue("SmtpServerUsername",txtUsername.Text);
            key.SetValue("SmtpServerPassword",txtPassword.Text);
            key.SetValue("SendFrom", txtSendFrom.Text);
            try
            {
                int port = Convert.ToInt32(txtPort.Text);
                key.SetValue("SmtpServerPort", txtPort.Text);
            }
            catch
            {
                key.SetValue("SmtpServerPort", "25");
            }

            try {
                int mailDelay = Convert.ToInt32(txtEmailDelay.Text);
                key.SetValue("EmailDelay", txtEmailDelay.Text);
            } catch {
                key.SetValue("EmailDelay", "45");
            }
        }

        public void LoadSettings()
        {
            //Disks
            RegistryKey key = Registry.LocalMachine.OpenSubKey(_RegistryRoot + @"\Disks");
            if (key != null)
            {
                string[] keys = key.GetValueNames();
                foreach (string k in key.GetValueNames())
                {
                    if (clbDisks.FindString(k + ":") > -1)
                    {
                        clbDisks.SetItemChecked(clbDisks.FindString(k + ":"), true);
                    }
                }
            }

            //Free space threshold
            key = Registry.LocalMachine.OpenSubKey(_RegistryRoot + @"\Threshold");
            if (key != null)
            {
                key = Registry.LocalMachine.CreateSubKey(_RegistryRoot + @"\Threshold");
            }
            key = Registry.LocalMachine.OpenSubKey(_RegistryRoot + @"\Threshold");
            if (key != null)
            {
                cboAmount.SelectedIndex = cboAmount.FindStringExact(key.GetValue("Amount", "1").ToString());
                cboUnit.SelectedIndex = cboUnit.FindStringExact(key.GetValue("Unit", "GB").ToString());
            }
            else
            {
                cboAmount.SelectedIndex = 0;
                cboUnit.SelectedIndex = 0;
            }

            //Email addresses
            key = Registry.LocalMachine.OpenSubKey(_RegistryRoot);
            string[] EmailAddresses = key.GetValue("EmailAddresses", "").ToString().Split(char.Parse(";"));
            foreach (string s in EmailAddresses)
            {
                if (!string.IsNullOrEmpty(s))
                {
                    DataGridViewRow dr = new DataGridViewRow();
                    dgEmailAddresses.Rows.Add(s);
                }
            }

            //Email options
            key = Registry.LocalMachine.OpenSubKey(_RegistryRoot);

            string sMachineName = "";
            string sSmtpServer = "";
            string sSendFrom = "";
            string sSmtpServerPort = "";
            string sSmtpServerUserName = "";
            string sSmtpServerPassword = "";
            string sEmailDelay = "";

            if (string.IsNullOrEmpty(key.GetValue("MachineName", "").ToString())) {
                sMachineName = System.Windows.Forms.SystemInformation.ComputerName;
            } else {
                sMachineName = key.GetValue("MachineName", "").ToString();
            }

            if (string.IsNullOrEmpty(key.GetValue("SmtpServer", "").ToString())) {
                sSmtpServer = "127.0.0.1";
            } else {
                sSmtpServer = key.GetValue("SmtpServer", "").ToString();
            }

            if (string.IsNullOrEmpty(key.GetValue("SendFrom", "").ToString())) {
                sSendFrom = "change_me@domain.com";
            } else {
                sSendFrom = key.GetValue("SendFrom", "").ToString();
            }

            if (string.IsNullOrEmpty(key.GetValue("SmtpServerPort", "").ToString())) {
                sSmtpServerPort = "25";
            } else {
                sSmtpServerPort = key.GetValue("SmtpServerPort", "").ToString();
            }

            if (string.IsNullOrEmpty(key.GetValue("SmtpServerUsername", "").ToString())) {
                sSmtpServerUserName = "";
            } else {
                sSmtpServerUserName = key.GetValue("SmtpServerUsername", "").ToString();
            }

            if (string.IsNullOrEmpty(key.GetValue("SmtpServerPassword", "").ToString())) {
                sSmtpServerPassword = "";
            } else {
                sSmtpServerPassword = key.GetValue("SmtpServerPassword", "").ToString();
            }

            if (string.IsNullOrEmpty(key.GetValue("EmailDelay", "").ToString())) {
                sEmailDelay = "45";
            } else {
                sEmailDelay = key.GetValue("EmailDelay", "").ToString();
            }

            txtMachineName.Text = sMachineName;
            txtSmtpServer.Text = sSmtpServer;
            txtSendFrom.Text = sSendFrom;
            txtPort.Text = sSmtpServerPort;
            txtUsername.Text = sSmtpServerUserName;
            txtPassword.Text = sSmtpServerPassword;
            txtEmailDelay.Text = sEmailDelay;

        }

        private void RestartService()
        {
            try
            {
                ServiceController controller = new ServiceController();
                controller.MachineName = ".";
                controller.ServiceName = "Meerkat";
                string status = controller.Status.ToString();

                // Stop the service
                if (controller.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                {
                    controller.Stop();
                    Thread.Sleep(1500);//wait for the stop to take effect
                    if (clbDisks.CheckedItems.Count > 0)
                    {
                        // Start the service
                        controller.Start();
                        //Thread.Sleep(3000);
                    }
                }
            }
            catch { }
        }

        private void btnDisks_Click(object sender, EventArgs e)
        {
            panelDisks.Location = new Point(-2, 83);
            panelDisks.Height = 239;
            panelDisks.Width = 308;
            panelDisks.Visible = true;
            panelEmail.Visible = false;
            panelOptions.Visible = false;
        }

        private void btnEmail_Click(object sender, EventArgs e)
        {
            panelEmail.Location = new Point(-2, 83);
            panelEmail.Height = 239;
            panelEmail.Width = 308;
            panelEmail.Visible = true;
            panelDisks.Visible = false;
            panelOptions.Visible = false;
        }

        private void btnOptions_Click(object sender, EventArgs e)
        {
            panelOptions.Location = new Point(-2, 83);
            panelOptions.Height = 239;
            panelOptions.Width = 308;
            panelOptions.Visible = true;
            panelDisks.Visible = false;
            panelEmail.Visible = false;
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            SaveAllSettings();
            RestartService();
        }

        /* SAVE CHANGES ON THE FLY */

        private void clbDisks_SelectedValueChanged(object sender, EventArgs e)
        {
            SaveDiskSettings();
        }

        private void dgEmailAddresses_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
        {
            SaveEmailAddresses();
        }

        private void dgEmailAddresses_CurrentCellChanged(object sender, EventArgs e)
        {
            SaveEmailAddresses();
        }

        private void txtSendFrom_TextChanged(object sender, EventArgs e)
        {
            SaveEmailOptions();
        }

        private void txtMachineName_TextChanged(object sender, EventArgs e)
        {
            SaveEmailOptions();
        }

        private void txtSmtpServer_TextChanged(object sender, EventArgs e)
        {
            SaveEmailOptions();
        }

        private void txtPort_TextChanged(object sender, EventArgs e)
        {
            SaveEmailOptions();
        }

        private void txtUsername_TextChanged(object sender, EventArgs e)
        {
            SaveEmailOptions();
        }

        private void txtPassword_TextChanged(object sender, EventArgs e)
        {
            SaveEmailOptions();
        }

        private void txtEmailDelay_TextChanged(object sender, EventArgs e) {
            SaveEmailOptions();
        }

        private void cboAmount_SelectedIndexChanged(object sender, EventArgs e)
        {
            SaveAlertSettings();
        }

        private void cboUnit_SelectedIndexChanged(object sender, EventArgs e)
        {
            SaveAlertSettings();
        }
    }
}
